package za.org.jcicada.genss.lifecycle.impl;

/**
 * LifeCycleServerProxy.java
 *
 * @author Simon Cross
 *
 * Created on February 11, 2009, 14:48
 */

import java.net.URI;

import za.org.jcicada.comms.IConnector;
import za.org.jcicada.comms.impl.MessageListenerBase;
import za.org.jcicada.comms.impl.ProxyBase;
import za.org.jcicada.genss.SystemURN;
import za.org.jcicada.genss.lifecycle.ILifeCycleClient;
import za.org.jcicada.genss.lifecycle.ILifeCycleServer;
import za.org.jcicada.genss.lifecycle.LogLevel;
import za.org.jcicada.genss.lifecycle.messages.HaltReply;
import za.org.jcicada.genss.lifecycle.messages.HaltRequest;
import za.org.jcicada.genss.lifecycle.messages.PingReply;
import za.org.jcicada.genss.lifecycle.messages.PingRequest;
import za.org.jcicada.genss.lifecycle.messages.ReconnectReply;
import za.org.jcicada.genss.lifecycle.messages.ReconnectRequest;
import za.org.jcicada.genss.lifecycle.messages.RestartReply;
import za.org.jcicada.genss.lifecycle.messages.RestartRequest;
import za.org.jcicada.genss.lifecycle.messages.SetLogLevelReply;
import za.org.jcicada.genss.lifecycle.messages.SetLogLevelRequest;

/**
 * ILifeCycleServer implementation that proxies requests through to
 * a remote lifecycle subject.
 */
public class LifeCycleServerProxy extends ProxyBase<ILifeCycleClient> implements ILifeCycleServer {

    /**
     * Create an LifeCycleServerProxy.
     *
     * @param connector IConnector object for creating connections to the remote subject.
     */
    public LifeCycleServerProxy(IConnector connector) {
        super(connector);
    }
    
    /**
     * Create an LifeCycleServerProxy.
     *
     * @param locationURI address of the acceptor.
     */
    public LifeCycleServerProxy(URI locationURI) {
        super(locationURI);
    }

    @Override
    protected MessageListenerBase createReceiver(ILifeCycleClient client) {
        return new Receiver(client);
    }

    // ILifeCycleServer methods

    /**
     * Send HaltRequest.
     */
    public void requestHalt(ILifeCycleClient observer, SystemURN systemURN) {
        sendMessage(observer, new HaltRequest(systemURN));
    }

    /**
     * Send RestartRequest.
     */
    public void requestRestart(ILifeCycleClient observer, SystemURN systemURN) {
        sendMessage(observer, new RestartRequest(systemURN));
    }

    /**
     * Send SetLogLevelRequest.
     */
    public void requestSetLogLevel(ILifeCycleClient observer, SystemURN systemURN, LogLevel level) {
        sendMessage(observer, new SetLogLevelRequest(systemURN, level));
    }
    
    /**
     * Send ReconnectRequest.
     */
    public void requestReconnect(ILifeCycleClient observer, SystemURN systemURN) {
        sendMessage(observer, new ReconnectRequest(systemURN));
    }
    
    public void requestPing(ILifeCycleClient observer, SystemURN systemURN) {
    	sendMessage(observer, new PingRequest(systemURN));
    }
    
    /**
     * Implementation of IMessageListener that dispatches messages to an ILifeCycleClient.
     */
    public class Receiver extends MessageListenerBase {

        /**
         * Handle to callback object for messages from the subject to the observer.
         */
        ILifeCycleClient observer;

        public Receiver(ILifeCycleClient observer) {
            this.observer = observer;
        }

        public void onClose() throws Exception {
            observer.informDisconnect();
        }

        // dispatch methods

        /**
         * Dispatch HaltReply.
         */
        public void lifecycleHaltReply(HaltReply msg) {
            observer.replyHalt(msg.getResult(), msg.getSystemURN());
        }

        /**
         * Dispatch RestartReply.
         */
        public void lifecycleRestartReply(RestartReply msg) {
            observer.replyRestart(msg.getResult(), msg.getSystemURN());
        }

        /**
         * Dispatch SetLogLevelReply.
         */
        public void lifecycleSetLogLevelReply(SetLogLevelReply msg) {
            observer.replySetLogLevel(msg.getResult(), msg.getSystemURN(), msg.getLevel());
        }
        
        /**
         * Dispatch ReconnectReply.
         */
        public void lifecycleReconnectReply(ReconnectReply msg) {
            observer.replyReconnect(msg.getResult(), msg.getSystemURN());
        }
        
        public void lifecyclePingReply(PingReply msg) {
        	observer.replyPing(msg.getResult(), msg.getSystemURN());
        }
    }
}
